package com.example.maze;

import tw.fc.agui.GrCanvas;
import tw.fc.agui.GraphicObj;
import android.graphics.Color;

public class Dpad extends GraphicObj {
   //[ ========== static part ==========
   ////[ 按鈕左上角的點座標
   private static int   left_x ,    left_y, 
                        down_x ,    down_y, 
                        right_x,   right_y, 
                        up_x   ,      up_y, 
                       mark_x  ,    mark_y,
                       flag_x  ,    flag_y,
                      flagPut_x, flagPut_y,
                      flagFly_x, flagFly_y,
                      radar_x,   radar_y; 
   ////]
   private static final int KEY_SIZE       = 40,
                            FLAG_ITEM_WIDTH= 65,
                            FLAG_ITEM_HEIGHT=90;
   private final static int WEST = 0,
                            SOUTH= 1,
                            EAST = 2,
                            NORTH= 3;
   //] ========== static part ==========  
   
   private int      screenWidth, screenHeight;
   private int      M        = DataSet.MAZE_M, 
                    N        = DataSet.MAZE_N;
   private int      myPosM   = DataSet.myPosM, 
                    myPosN   = DataSet.myPosN;
   private Cell[][] mazeCells= DataSet.MAZE_CELLS;
   private boolean  isMenuOpen= false;
   private boolean  isRadarOpen= false;
   
   //[ ---------- construct ----------
   public Dpad(int w, int h) { screenWidth= w; screenHeight=h; }
   //] ---------- construct ----------
   
   private void drawKey(GrCanvas g, int px, int py, int size, int dc, int fc, String s, int dx, int dy) {
      int oldColor= g.getColor();
      g.setColor(fc);
      g.fillRoundRect(px, py , size, size, 10, 10);
      g.setColor(Color.RED);
      g.setTextSize(30.0f);
      g.drawString(s,px+dx,py+dy);
      g.setColor(dc);
      g.drawRoundRect(px, py , size, size, 10, 10);
      g.setColor(oldColor);
   }  
   private void drawMark(GrCanvas g, int px, int py, int size, int dc, int fc, String s, int dx, int dy) {
      int oldColor= g.getColor();
      g.setColor(fc);
      g.fillRoundRect(px, py , size, size, 10, 10);
      g.setColor(Color.BLACK);
      g.setTextSize(30.0f);
      g.drawString(s,px+dx,py+dy);
      g.setColor(dc);
      g.drawRoundRect(px, py , size, size, 10, 10);
      g.setColor(oldColor);
   }
   private void drawFlag(GrCanvas g, int px, int py, int size, int dc, int fc, String s, int dx, int dy) {
      int oldColor= g.getColor();
      g.setColor(fc);
      g.fillRoundRect(px, py , size, size, 10, 10);
      g.setColor(Color.BLUE);
      g.setTextSize(30.0f);
      g.drawString(s,px+dx,py+dy);
      g.setColor(dc);
      g.drawRoundRect(px, py , size, size, 10, 10);
      g.setColor(oldColor);
   }
   private void drawRadar(GrCanvas g, int px, int py, int size, int dc, int fc, String s, int dx, int dy) {
      int oldColor= g.getColor();
      g.setColor(fc);
      g.fillRoundRect(px, py , size, size, 10, 10);
      g.setColor(Color.BLACK);
      g.setTextSize(30.0f);
      g.drawString(s,px+dx,py+dy);
      g.setColor(dc);
      g.drawRoundRect(px, py , size, size, 10, 10);
      g.setColor(oldColor);
   }
   private void drawMenu(GrCanvas g, int px, int py, int fx, int fy) {
      int oldColor= g.getColor();
      g.setColor(Color.rgb(0,0,250));
      g.fillRect(px, py, FLAG_ITEM_WIDTH, FLAG_ITEM_HEIGHT);
      g.setColor(Color.WHITE);
      g.drawRect(px, py, FLAG_ITEM_WIDTH, FLAG_ITEM_HEIGHT);
      g.drawLine(px, py+FLAG_ITEM_HEIGHT/2, px+FLAG_ITEM_WIDTH, py+FLAG_ITEM_HEIGHT/2);
      g.drawString("PUT!",px,py+FLAG_ITEM_HEIGHT/8*3);
      g.drawString(" FLY!",fx,fy+FLAG_ITEM_HEIGHT/8*3);
      g.setColor(oldColor);
   }
   @Override
   public void paintTo(GrCanvas g) {
      //[ 半透明綠色面板
      int oldColor= g.getColor();
      g.setColor(Color.GREEN);
      g.setAlpha(80); 
      int px= 0, py=screenHeight*3/5, w=screenWidth, h= 150;
      g.fillRect(px, py, w, h);
      //]
      //[ 方向鍵及 Mark鍵
      left_x = w-150; left_y = py+60;
      down_x = w-100; down_y = py+110;
      right_x= w-50;  right_y= py+60;
      up_x   = w-100; up_y   = py+5;
      mark_x = px+50; mark_y = py+60;
      flag_x = px+120; flag_y= py+60;
      flagPut_x= flag_x; flagPut_y= flag_y-100;
      flagFly_x= flag_x; flagFly_y= flagPut_y+FLAG_ITEM_HEIGHT/2;
      radar_x = px+190; radar_y= py+60;
      drawKey(g,     left_x,   left_y, KEY_SIZE,    Color.BLACK,  Color.YELLOW, "←",  5, 27);   // left
      drawKey(g,     down_x,   down_y, KEY_SIZE,    Color.BLACK,  Color.YELLOW, "↓", 13, 29);   // down
      drawKey(g,    right_x,  right_y, KEY_SIZE,    Color.BLACK,  Color.YELLOW, "→",  5, 27);   // right
      drawKey(g,       up_x,     up_y, KEY_SIZE,    Color.BLACK,  Color.YELLOW, "↑", 13, 29);   // up
      drawMark(g,     mark_x,   mark_y, KEY_SIZE, Color.MAGENTA, Color.MAGENTA, "M",  8, 30);   // mark
      drawFlag(g,    flag_x,   flag_y, KEY_SIZE,    Color.BLACK,    Color.RED, "F", 12, 30);   // flag
      drawRadar(g,    radar_x,   radar_y, KEY_SIZE,    Color.BLACK,    Color.WHITE, "R", 10, 30);   // Radar
      //]
      if(isMenuOpen) {
         drawMenu(g, flagPut_x, flagPut_y, flagFly_x, flagFly_y);
      }
      g.setColor(oldColor);      
   }
   
//   private int fromM, fromN, toM, toN;
//   private void updateFromMFromNToMToN() {
//      DataSet.fromM = fromM;
//      DataSet.fromN = fromN;
//      DataSet.toM   = toM;
//      DataSet.toN   = toN;
//   }
//   private void updateMyPosition() {
//      DataSet.myPosM= myPosM; 
//      DataSet.myPosN= myPosN;
//   }
//   private void transformVisualRange() {
//      fromM= myPosM-DataSet.visualRangeM/2; 
//      fromN= myPosN-DataSet.visualRangeN/2;
//      toM= fromM+(DataSet.visualRangeM-1); // because 0..M-1
//      toN= fromN+(DataSet.visualRangeN-1); // because 0..N-1
//      
//      if(fromM<0) {
//         fromM= 0;
//         toM  = fromM+(DataSet.visualRangeM-1); 
//      } else if(toM>=DataSet.MAZE_M) {
//         toM  = DataSet.MAZE_M-1;
//         fromM= toM-(DataSet.visualRangeM-1);                  
//      }
//      
//      if(fromN<0) {
//         fromN= 0;
//         toN  = fromN+(DataSet.visualRangeN-1);
//      } else if(toN>=DataSet.MAZE_N) {
//         toN  = DataSet.MAZE_N-1;
//         fromN= toN-(DataSet.visualRangeN-1);
//      }
//      updateFromMFromNToMToN();
//      updateMyPosition();
//      DataSet.positionChanged();
//   }
   private void updateMyPosition() {
      myPosM= DataSet.myPosM; 
      myPosN= DataSet.myPosN;
//      fromM = DataSet.fromM;
//      fromN = DataSet.fromN;
//      toM   = DataSet.toM;
//      toN   = DataSet.toN;
//      midM  = DataSet.midM;
//      midN  = DataSet.midN;
   }
   private void markTrace() {
      mazeCells[myPosM][myPosN].trace= Cell.YES;
   }
   private void moveLeft() {
      updateMyPosition();
      if(myPosN>0) {
         //[ 非牆或邊界才能前進
         if(!mazeCells[myPosM][myPosN].walls[WEST] && 
            !mazeCells[myPosM][myPosN].borders[WEST]) {
            //[ 舊位置清空
            mazeCells[myPosM][myPosN].state= Cell.NON_FOCUS;  
            //[ 新位置標示
            mazeCells[myPosM][--myPosN].state= Cell.FOCUS;
            //[ 走至半個螢幕
//            if(myPosN==midN-1) {
//               //[ 改變顯示範圍
//               fromN= (fromN==0)?fromN:fromN-1; // 防 outOfBoundsException
//               toN  = fromN+DataSet.visualRangeN;
//               midN = DataSet.visualRangeN/2+fromN;
//               updateFromMFromNToMToN();
//            }
//            updateMyPosition();
            DataSet.resetMyPosition(myPosM, myPosN);            
            markTrace();
            DataSet.positionChanged();
         }
      }
   }
   private void moveRight() {
      updateMyPosition();
      if(myPosN<N-1) { 
         if(!mazeCells[myPosM][myPosN].walls[EAST] && 
            !mazeCells[myPosM][myPosN].borders[EAST]) {
            mazeCells[myPosM][myPosN].state= Cell.NON_FOCUS; 
            mazeCells[myPosM][++myPosN].state= Cell.FOCUS;
//            if(myPosN==midN+1) {
//               //[ 改變顯示範圍
//               toN  = (toN==(N-1))?toN:toN+1; // 防 outOfBoundsException
//               fromN= toN-DataSet.visualRangeN;
//               midN = DataSet.visualRangeN/2+fromN;   
//               updateFromMFromNToMToN();
//            }
//            updateMyPosition();
            DataSet.resetMyPosition(myPosM, myPosN);
            markTrace();
            DataSet.positionChanged();
         }
      }
   }
   private void moveUp() {
      updateMyPosition();
      if(myPosM>0){
         if(!mazeCells[myPosM][myPosN].walls[NORTH] && 
            !mazeCells[myPosM][myPosN].borders[NORTH]) {
            mazeCells[myPosM][myPosN].state= Cell.NON_FOCUS;   
            mazeCells[--myPosM][myPosN].state= Cell.FOCUS;
//            if(myPosM==midM-1) {
//               //[ 改變顯示範圍
//               fromM= (fromM==0)?fromM:fromM-1; // 防 outOfBoundsException
//               toM  = fromM+DataSet.visualRangeM;
//               midM = DataSet.visualRangeM/2+fromM;                                  
//               updateFromMFromNToMToN();
//            }
//            updateMyPosition();
            DataSet.resetMyPosition(myPosM, myPosN);
            markTrace();
            DataSet.positionChanged();
         }
      }
   }
   private void moveDown() {
      updateMyPosition();
      if(myPosM<M-1) {
         if(!mazeCells[myPosM][myPosN].walls[SOUTH] && 
            !mazeCells[myPosM][myPosN].borders[SOUTH]) {
            mazeCells[myPosM][myPosN].state= Cell.NON_FOCUS;   
            mazeCells[++myPosM][myPosN].state= Cell.FOCUS;
//            if(myPosM==midM+1) {
//               //[ 改變顯示範圍
//               toM  = (toM==(M-1))?toM:toM+1; // 防 outOfBoundsException
//               fromM= toM-DataSet.visualRangeM; 
//               midM = DataSet.visualRangeM/2+fromM; 
//               updateFromMFromNToMToN();
//            }
//            updateMyPosition();
            DataSet.resetMyPosition(myPosM, myPosN);
            markTrace();
            DataSet.positionChanged();
         }
      }
   }
   
   private void markPressed() {
      if(mazeCells[myPosM][myPosN].mark==Cell.NO) {
         mazeCells[myPosM][myPosN].mark= Cell.YES;   
      } else if(mazeCells[myPosM][myPosN].mark== Cell.YES){
         mazeCells[myPosM][myPosN].mark= Cell.NO;   
      }
      DataSet.markChanged();
   }   
   private void flagMenuPressed() {
      DataSet.markChanged();
      if(isMenuOpen) {
         isMenuOpen= false;
      } else {         
         isMenuOpen= true;
      }    
   }
   private void radarPressed() {
      if(isRadarOpen) {
         DataSet.hideRadar();
         isRadarOpen= false;
      } else {
         DataSet.showRadar();
         isRadarOpen= true;
      }    
   }
   private void flagItemPressed(int px, int py) {     
      //[ if PUT!
      if(flagPut_x<= px && flagPut_y<= py && 
         px<=flagPut_x+FLAG_ITEM_WIDTH && 
         py<=flagPut_y+FLAG_ITEM_HEIGHT/2) {
         //[ To check the amount of flags 
         if(Flag.NUM_OF_FLAG<Flag.MAXIMUM_FLAG) {
            //[ push flag
//            DataSet.flags.push(new Flag(myPosM, myPosN,
//                                        fromM , fromN ,
//                                        toM   , toN   ,
//                                        midM  , midN));
            DataSet.flags.push(new Flag(myPosM, myPosN));
            mazeCells[myPosM][myPosN].flag= Cell.YES;
            Flag.NUM_OF_FLAG++;
         }
      //[ if FLY!
      } else if(flagFly_x<= px && flagFly_y<= py && 
                px<=flagFly_x+FLAG_ITEM_WIDTH && 
                py<=flagFly_y+FLAG_ITEM_HEIGHT/2) {
            if(Flag.NUM_OF_FLAG>0){
               //[ fly!
               mazeCells[myPosM][myPosN].state= Cell.NON_FOCUS; 
               //[ pop flag
               Flag theFlag= DataSet.flags.pop();
               //[ reset the position
               this.myPosM= theFlag.myPosM; this.myPosN= theFlag.myPosN;
               DataSet.resetMyPosition(myPosM, myPosN);
//               updateMyPosition();
//               //[ reset visual range
//               fromM=theFlag.fromM; fromN=theFlag.fromN; 
//               toM=theFlag.toM; toN=theFlag.toN; 
//               midM=theFlag.midM; midN=theFlag.midN; 
//               updateFromMFromNToMToN();            
               mazeCells[myPosM][myPosN].flag= Cell.NO; 
               Flag.NUM_OF_FLAG--;               
               //[ appear!
               mazeCells[myPosM][myPosN].state= Cell.FOCUS; 
            }
      }
      DataSet.markChanged();
   }
   @Override
   public void forDown(android.view.MotionEvent e) {
      final int px= (int)e.getX() ,py= (int)e.getY();
      if(left_x<=px         && left_y<=py  && px<=left_x+KEY_SIZE  && py<=left_y+KEY_SIZE) {
         this.moveLeft();
      } else if(down_x<=px  && down_y<=py  && px<=down_x+KEY_SIZE  && py<=down_y+KEY_SIZE) {
         this.moveDown();
      } else if(right_x<=px && right_y<=py && px<=right_x+KEY_SIZE && py<=right_y+KEY_SIZE) {
         this.moveRight();
      } else if(up_x<=px    && up_y<=py    && px<=up_x+KEY_SIZE    && py<=up_y+KEY_SIZE) {
         this.moveUp();
      } else if(mark_x<=px   && mark_y<=py   && px<=mark_x+KEY_SIZE   && py<=mark_y+KEY_SIZE) {
         this.markPressed();
      } else if(flag_x<=px   && flag_y<=py   && px<=flag_x+KEY_SIZE   && py<=flag_y+KEY_SIZE) {
         this.flagMenuPressed();
      } else if(radar_x<=px   && radar_y<=py   && px<=radar_x+KEY_SIZE   && py<=radar_y+KEY_SIZE) {
         this.radarPressed();
      }
      
      if(isMenuOpen) {
         flagItemPressed(px,py);
      }
   }
   
   @Override
   public boolean contains(tw.fc.agui.ImuV2D at) {
      int mx= at.ix(), my= at.iy();
      if(0<=mx && screenHeight*3/5<=my && mx<=screenWidth && my<=screenHeight) {
         return true;
      }
      return false;  //: 預設成不佔空間. 通常要override.
   }
}
